ListView(2) 您所在的位置:网站首页 listview 自定义 触屏 ListView(2)

ListView(2)

2023-08-10 05:40| 来源: 网络整理| 查看: 265

之前介绍了三种adapter:ArrayAdapter、SimpleAdapter和SimpleCursorAdapter。

使用android提供的adapter来绘制列表的话,列表的每一项的显示都是一样的。为了实现ListView的单双行不同颜色显示,需要自定义adapter的子类。adapter的常用子类有BaseAdapter、ArrayAdapter、SimpleAdapter等,下面介绍自定义BaseAdapter和ArrayAdapter的实现。

1.自定义BaseAdapter

效果图如下:

    

在上一篇《ListView(1)——各种Adapter的使用》的基础上,为了实现ListView的单双行不同颜色显示,需要自定义adapter的子类,而activity_main.xml文件和list_item.xml文件都不需要更改,MainActivity.java代码修改如下:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 图片资源的ID int[] images = new int[] { R.drawable.item_img_a, R.drawable.item_img_b, R.drawable.item_img_c, R.drawable.item_img_d, R.drawable.item_img_e }; List data = new ArrayList(); for (int i = 0; i < 5; i++) { HashMap map = new HashMap(); map.put("ItemImage", images[i]); map.put("ItemTitle", "This is Title " + i); map.put("ItemText", "This is text " + i); data.add(map); } // 绑定XML中的ListView,作为Item的容器 ListView listView = (ListView) findViewById(R.id.list); MyBaseAdapter adapter = new MyBaseAdapter(MainActivity.this, data); listView.setAdapter(adapter); }

下面我们实现自定义的MyBaseAdapter类。MyBaseAdapter类继承自BaseAdapter类,BaseAdapter为抽象类,继承它需要实现如下方法,因此具有较高的灵活性。

public class MyBaseAdapter extends BaseAdapter { @Override public int getCount() { // TODO Auto-generated method stub return 0; } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub return null; } }

ListView在绘制时首先会调用getCount()方法得到绘制次数,然后通过getView()方法一层一层进行绘制,所以我们可以在getView()方法中根据position(当前绘制的ID)来的修改绘制内容。而getItem()和getItemId()则在需要处理和取得Adapter中的数据时调用。

public class MyBaseAdapter extends BaseAdapter { private int[] colors = new int[] { 0xff3cb371, 0xffa0a0a0 }; private Context mContext; private List dataList; public MyBaseAdapter(Context context, List dataList) { this.mContext = context; this.dataList = dataList; } @Override public int getCount() { return dataList.size(); } @Override public HashMap getItem(int position) { return dataList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = LayoutInflater.from(mContext).inflate( R.layout.list_item, null); holder.image = (ImageView) convertView.findViewById(R.id.ItemImage); holder.title = (TextView) convertView.findViewById(R.id.ItemTitle); holder.text = (TextView) convertView.findViewById(R.id.ItemText); // 将holder绑定到convertView convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } // 向ViewHolder中填入的数据 holder.image.setImageResource((Integer) getItem(position).get( "ItemImage")); holder.title.setText((String) getItem(position).get("ItemTitle")); holder.text.setText((String) getItem(position).get("ItemText")); int colorPos = position % colors.length; convertView.setBackgroundColor(colors[colorPos]); return convertView; } /** * ViewHolder类用以储存item中控件的引用 */ final class ViewHolder { ImageView image; TextView title; TextView text; } } getView() 方法用来获得绘制每个item的View对象,如果 每次 getView() 被执行都new出一个View对象,长此以往会产生很大的消耗,特别当item中还有Bitmap等,甚至会造成OOM的错误导致程序崩溃。从上面的代码可以看到 getView()有一个convertView参数,这个参数用来缓存View对象。当ListView滑动的过程中,会有item被滑出屏幕而不再被使用,这时候Android会回收这个item的view,这个view也就是这里的convertView。这样如果convertView不为null,就不用new出一个新的View对象,只用往convertView中填充新的item,这样就省去了new View的大量开销。

在上面的代码中,在缓存convertView减少new View开销的同时,通过setTag()方法将数据结构ViewHolder绑定到convertView,从而利用ViewHolder存储convertView中控件对象的引用,这样避免每次调用findViewById()方法。

2.自定义ArrayAdapter

在开发中需要将对象显示在listview中,这时候使用ArrayAdapter来显示指定对象类型。下面自定义ArrayAdapter实现上一节中自定义BaseAdapter实现的同样的效果,首先定义要显示的对象,代码如下ItemBean.java。

public class ItemBean { private int image; private String title; private String text; public ItemBean(int image, String title, String text) { this.image = image; this.title = title; this.text = text; } public int getImage() { return image; } public String getTitle() { return title; } public String getText() { return text; } } 和上一节一样,为了实现ListView的单双行不同颜色显示,需要自定义adapter的子类,而activity_main.xml文件和list_item.xml文件都不需要更改,MainActivity.java代码修改如下:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 图片资源的ID int[] images = new int[] { R.drawable.item_img_a, R.drawable.item_img_b, R.drawable.item_img_c, R.drawable.item_img_d, R.drawable.item_img_e }; ArrayList data = new ArrayList(); for (int i = 0; i < 5; i++) { ItemBean itemBean = new ItemBean(images[i], "This is Title " + i, "This is text " + i); data.add(itemBean); } // 绑定XML中的ListView,作为Item的容器 ListView listView = (ListView) findViewById(R.id.list); MyArrayAdapter adapter = new MyArrayAdapter(MainActivity.this, R.layout.list_item, data); listView.setAdapter(adapter); } 接下来自定义继承自ArrayAdapter的MyArrayAdapter类,继承ArrayAdapter只需要重写getView()方法就可以实现与上一节相同的效果,并且不用保存List对象引用。

public class MyArrayAdapter extends ArrayAdapter { private int[] colors = new int[] { 0xff3cb371, 0xffa0a0a0 }; private Context mContext; private int resource; public MyArrayAdapter(Context context, int resource, List data) { super(context, resource, data); this.mContext = context; this.resource = resource; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = LayoutInflater.from(mContext).inflate(resource, null); holder.image = (ImageView) convertView.findViewById(R.id.ItemImage); holder.title = (TextView) convertView.findViewById(R.id.ItemTitle); holder.text = (TextView) convertView.findViewById(R.id.ItemText); // 将holder绑定到convertView convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } // 向ViewHolder中填入的数据 holder.image.setImageResource(getItem(position).getImage()); holder.title.setText(getItem(position).getTitle()); holder.text.setText(getItem(position).getText()); int colorPos = position % colors.length; convertView.setBackgroundColor(colors[colorPos]); return convertView; } /** * ViewHolder类用以储存item中控件的引用 */ final class ViewHolder { ImageView image; TextView title; TextView text; } }

参考文章:

http://www.open-open.com/lib/view/open1339485728006.html



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有